"""
AI聊天GUI应用
使用tkinter创建Windows桌面聊天界面
"""
import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox
import threading
from datetime import datetime
from ai_service import ai_service


class ChatGUI:
    """聊天GUI主窗口类"""

    def __init__(self):
        """初始化聊天界面"""
        self.root = tk.Tk()
        self.setup_window()
        self.create_widgets()
        self.setup_ai_callback()

    def setup_window(self):
        """设置主窗口属性"""
        self.root.title("AI聊天助手")
        self.root.geometry("800x600")
        self.root.minsize(600, 400)

        # 设置窗口图标（如果有的话）
        # self.root.iconbitmap("icon.ico")

        # 配置样式
        style = ttk.Style()
        style.theme_use('clam')

    def create_widgets(self):
        """创建界面组件"""
        # 创建主框架
        main_frame = ttk.Frame(self.root, padding="10")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

        # 配置网格权重
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
        main_frame.columnconfigure(0, weight=1)
        main_frame.rowconfigure(1, weight=1)

        # 创建顶部工具栏
        self.create_toolbar(main_frame)

        # 创建聊天显示区域
        self.create_chat_area(main_frame)

        # 创建输入区域
        self.create_input_area(main_frame)

        # 创建状态栏
        self.create_status_bar()

    def create_toolbar(self, parent):
        """创建工具栏"""
        toolbar_frame = ttk.Frame(parent)
        toolbar_frame.grid(row=0, column=0, sticky=(tk.W, tk.E), pady=(0, 10))

        # 清空历史按钮
        ttk.Button(
            toolbar_frame,
            text="清空历史",
            command=self.clear_history
        ).pack(side=tk.LEFT, padx=(0, 10))

        # 连接测试按钮
        ttk.Button(
            toolbar_frame,
            text="测试连接",
            command=self.test_connection
        ).pack(side=tk.LEFT, padx=(0, 10))

        # 分隔符
        ttk.Separator(toolbar_frame, orient=tk.VERTICAL).pack(side=tk.LEFT, fill=tk.Y, padx=10)

        # 模型信息标签
        self.model_label = ttk.Label(toolbar_frame, text=f"模型: {ai_service.model}")
        self.model_label.pack(side=tk.LEFT)

    def create_chat_area(self, parent):
        """创建聊天显示区域"""
        chat_frame = ttk.LabelFrame(parent, text="聊天记录", padding="5")
        chat_frame.grid(row=1, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 10))
        chat_frame.columnconfigure(0, weight=1)
        chat_frame.rowconfigure(0, weight=1)

        # 聊天记录文本框
        self.chat_display = scrolledtext.ScrolledText(
            chat_frame,
            wrap=tk.WORD,
            state=tk.DISABLED,
            font=("微软雅黑", 10),
            height=15
        )
        self.chat_display.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

        # 配置文本标签样式
        self.chat_display.tag_config("user", foreground="blue", font=("微软雅黑", 10, "bold"))
        self.chat_display.tag_config("assistant", foreground="green", font=("微软雅黑", 10))
        self.chat_display.tag_config("system", foreground="gray", font=("微软雅黑", 9, "italic"))
        self.chat_display.tag_config("error", foreground="red", font=("微软雅黑", 10))
        self.chat_display.tag_config("timestamp", foreground="gray", font=("微软雅黑", 8))

    def create_input_area(self, parent):
        """创建输入区域"""
        input_frame = ttk.LabelFrame(parent, text="输入消息", padding="5")
        input_frame.grid(row=2, column=0, sticky=(tk.W, tk.E))
        input_frame.columnconfigure(0, weight=1)

        # 输入文本框
        self.input_text = tk.Text(
            input_frame,
            wrap=tk.WORD,
            font=("微软雅黑", 10),
            height=4
        )
        self.input_text.grid(row=0, column=0, sticky=(tk.W, tk.E))
        input_frame.columnconfigure(0, weight=1)

        # 绑定回车键发送消息
        self.input_text.bind('<Control-Return>', lambda e: self.send_message())
        self.input_text.bind('<Shift-Return>', lambda e: None)  # 允许换行

        # 发送按钮框架
        button_frame = ttk.Frame(input_frame)
        button_frame.grid(row=1, column=0, sticky=(tk.E), pady=(5, 0))

        # 发送按钮
        self.send_button = ttk.Button(
            button_frame,
            text="发送 (Ctrl+Enter)",
            command=self.send_message
        )
        self.send_button.pack(side=tk.RIGHT)

        # 清空输入按钮
        ttk.Button(
            button_frame,
            text="清空",
            command=self.clear_input
        ).pack(side=tk.RIGHT, padx=(0, 10))

    def create_status_bar(self):
        """创建状态栏"""
        self.status_frame = ttk.Frame(self.root)
        self.status_frame.grid(row=1, column=0, sticky=(tk.W, tk.E))

        # 状态标签
        self.status_label = ttk.Label(self.status_frame, text="就绪", relief=tk.SUNKEN)
        self.status_label.pack(side=tk.LEFT, fill=tk.X, expand=True)

        # 字符计数标签
        self.char_count_label = ttk.Label(self.status_frame, text="字符: 0")
        self.char_count_label.pack(side=tk.RIGHT)

        # 绑定输入事件来更新字符计数
        self.input_text.bind('<KeyRelease>', self.update_char_count)
        self.input_text.bind('<Button-1>', self.update_char_count)

    def setup_ai_callback(self):
        """设置AI响应回调"""
        ai_service.set_response_callback(self.on_ai_response)

    def update_char_count(self, event=None):
        """更新字符计数"""
        text_length = len(self.input_text.get("1.0", tk.END).strip())
        self.char_count_label.config(text=f"字符: {text_length}")

    def send_message(self):
        """发送消息"""
        message = self.input_text.get("1.0", tk.END).strip()
        if not message:
            messagebox.showwarning("警告", "请输入消息内容")
            return

        # 显示用户消息
        self.add_message_to_display("用户", message, "user")

        # 清空输入框
        self.clear_input()

        # 更新状态
        self.update_status("正在等待AI回复...")

        # 禁用发送按钮防止重复发送
        self.send_button.config(state=tk.DISABLED)

        # 异步发送消息给AI
        ai_service.chat_async(message)

    def on_ai_response(self, response):
        """AI响应回调函数"""
        # 在主线程中更新UI
        self.root.after(0, self._update_ui_with_response, response)

    def _update_ui_with_response(self, response):
        """在主线程中更新UI显示AI回复"""
        if response.startswith("聊天出错:"):
            self.add_message_to_display("错误", response, "error")
        else:
            self.add_message_to_display("AI助手", response, "assistant")

        # 恢复发送按钮
        self.send_button.config(state=tk.NORMAL)

        # 更新状态
        self.update_status("就绪")

    def add_message_to_display(self, sender, message, tag="user"):
        """添加消息到聊天显示区域"""
        timestamp = datetime.now().strftime("%H:%M:%S")

        # 启用文本编辑
        self.chat_display.config(state=tk.NORMAL)

        # 添加时间戳
        self.chat_display.insert(tk.END, f"[{timestamp}] ", "timestamp")

        # 添加发送者
        self.chat_display.insert(tk.END, f"{sender}: ", tag)

        # 添加消息内容
        self.chat_display.insert(tk.END, f"{message}\n\n", tag)

        # 滚动到底部
        self.chat_display.see(tk.END)

        # 禁用文本编辑
        self.chat_display.config(state=tk.DISABLED)

    def clear_input(self):
        """清空输入框"""
        self.input_text.delete("1.0", tk.END)
        self.update_char_count()
        self.input_text.focus_set()

    def clear_history(self):
        """清空聊天历史"""
        result = messagebox.askyesno("确认", "确定要清空所有聊天历史吗？")
        if result:
            ai_service.clear_history()
            self.chat_display.config(state=tk.NORMAL)
            self.chat_display.delete("1.0", tk.END)
            self.chat_display.config(state=tk.DISABLED)
            self.add_message_to_display("系统", "聊天历史已清空", "system")
            self.update_status("聊天历史已清空")

    def test_connection(self):
        """测试AI服务连接"""
        self.update_status("正在测试连接...")

        def test_worker():
            try:
                if ai_service.test_connection():
                    self.root.after(0, lambda: self.on_connection_test(True))
                else:
                    self.root.after(0, lambda: self.on_connection_test(False))
            except Exception as e:
                self.root.after(0, lambda: self.on_connection_test(False, str(e)))

        thread = threading.Thread(target=test_worker, daemon=True)
        thread.start()

    def on_connection_test(self, success, error_msg=None):
        """连接测试结果回调"""
        if success:
            self.add_message_to_display("系统", "连接测试成功！", "system")
            self.update_status("连接正常")
            messagebox.showinfo("连接测试", "与AI服务的连接正常")
        else:
            error_info = f"连接失败: {error_msg}" if error_msg else "连接失败"
            self.add_message_to_display("错误", error_info, "error")
            self.update_status("连接失败")
            messagebox.showerror("连接测试", f"与AI服务的连接失败\n{error_info or ''}")

    def update_status(self, message):
        """更新状态栏"""
        self.status_label.config(text=message)

    def run(self):
        """运行应用程序"""
        # 添加欢迎消息
        self.add_message_to_display("系统", "欢迎使用AI聊天助手！", "system")
        self.add_message_to_display("系统", f"当前使用模型: {ai_service.model}", "system")

        # 测试初始连接
        self.test_connection()

        # 启动主循环
        self.root.mainloop()


def main():
    """主函数"""
    try:
        app = ChatGUI()
        app.run()
    except Exception as e:
        messagebox.showerror("错误", f"应用程序启动失败:\n{str(e)}")
        print(f"应用程序启动失败: {e}")


if __name__ == "__main__":
    main()